package utils;

/**
 * Created by fanzhenyu02 on 2020/2/14.
 */

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;


public class ProcessNetWxLog {


    public static Map<String, String> extractKeyParam(String param) {
        List<String> paramList = Arrays.asList(param.split("&"));
        Map<String, String> paramMap = new HashMap<>();
        for (String pa : paramList) {
            String[] paArr = pa.split("=");
            String key = paArr[0];
            String value = paArr.length >= 2 ? paArr[1] : "";
            if (key.equals("payType") || key.equals("merchantId") ||
                    key.equals("subMerchantId") || key.equals("bizMerchantNo")
                    || key.equals("appId") || key.equals("channelMerchantId")) {
                paramMap.put(key, value);
            }
        }

        return paramMap;
    }


    public static void run_analysis_netWx() throws Exception {
        // start to load file to memory
        Map<String, StringBuilder> map = new TreeMap<>();
        String line = null;
        try {
            FileInputStream inputStream = new FileInputStream("/Users/vonmax/Downloads/netunionwxpay_info.log_aa");
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

            while ((line = bufferedReader.readLine()) != null) {
                try {
                    String traceId = line.split("__traceId__=")[1].split("}#")[0];
                    if (map.containsKey(traceId)) {
                        StringBuilder builder = map.get(traceId);
                        builder.append(line).append("\n");
                    } else {
                        StringBuilder builder = new StringBuilder();
                        builder.append(line).append("\n");
                        map.put(traceId, builder);
                    }
                } catch (Exception e) {
                    //System.out.println("Skipp line :"+line);
                }
            }

            //close stream
            inputStream.close();
            bufferedReader.close();
        } catch (Exception e) {
            System.out.println(line);
            e.printStackTrace();
        }

        // start to analysis log
        Set<String> resultSet = new HashSet<>();
        List<List<String>> resultList = new ArrayList<>();


        int skipRepeatParamCount = 0;
        for (Map.Entry<String, StringBuilder> entry : map.entrySet()) {
            String logContent = entry.getValue().toString();
            try {
                if (!logContent.contains("验签字符串为:")) {
                    continue;
                }

                Map<String, String> paramMap = extractKeyParam(logContent.split("验签字符串为:")[1].split("2020-")[0]);
                String reqWxSubAppId = logContent.contains("<sub_appid>") ? logContent.split("<sub_appid>")[1].split("<\\/sub_appid>")[0] : "";

                String totalKey = reqWxSubAppId + paramMap.toString();
                if (resultSet.contains(totalKey)) {
                    ++skipRepeatParamCount;
                    continue;
                } else {
                    resultSet.add(totalKey);
                    List<String> currentLine = new ArrayList<>();

                    currentLine.add(StringUtils.isBlank(paramMap.get("payType")) ? "" : paramMap.get("payType"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("appId")) ? "" : paramMap.get("appId"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("merchantId")) ? "" : paramMap.get("merchantId"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("subMerchantId")) ? "" : paramMap.get("subMerchantId"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("bizMerchantNo")) ? "" : paramMap.get("bizMerchantNo"));
                    currentLine.add(StringUtils.isBlank(paramMap.get("channelMerchantId")) ? "" : paramMap.get("channelMerchantId"));
                    currentLine.add(reqWxSubAppId);

                    resultList.add(currentLine);
                }
            } catch (Exception ex) {
                System.out.println("Exception parse traceId: " + entry.getKey());
            }
        }

        String[] title = {"payType", "appId", "merchantId-对应微信 mch_id", "subMerchantId-对应微信 sub_mch_id",
                "bizMerchantNo-对应微信 attach", "channelMerchantId-对应微信 channel_id", "请求微信sub_appid"};
        //获取当前时间
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
        String date = df.format(new Date());// new Date()为获取当前系统时间，也可使用当前时间戳
        //存储Excel的路径
        String path = "/Users/vonmax/Downloads/netWxAnalysis_" + date + ".xlsx";
        createNewExcel(resultList, title, path);
        System.out.println("total skip repeat param count: " + skipRepeatParamCount);
    }

    /**
     * 重新创建新Excel文件
     *
     * @return
     */
    public static String createNewExcel(List<List<String>> objList, String[] title, String filePath) {
        try {
            // 创建Excel的工作书册 Workbook,对应到一个excel文档
            XSSFWorkbook wb = new XSSFWorkbook();
            // 创建Excel的工作sheet,对应到一个excel文档的tab
            XSSFSheet sheet = wb.createSheet("sheet1");
            for (int i = 0; i < title.length; i++) {
                sheet.setColumnWidth(i, 3200);// 设置单元格宽度，这里设置第一列的宽度
            }

            XSSFRow firstRow = sheet.createRow(0);
            // 设置字体
            XSSFFont font = wb.createFont();
            font.setBold(true);// 粗体字
            font.setFontName("宋体");
            // 设置单元格属性
            CellStyle cellStyle = wb.createCellStyle();
            cellStyle.setFont(font);// 设置字体
            // 生成表头
            for (int i = 0; i < title.length; i++) {
                XSSFCell cell = firstRow.createCell(i);
                cell.setCellValue(title[i]);
                cell.setCellStyle(cellStyle);// 设置单元格背景
            }
            // 生成数据
            for (int i = 0; i < objList.size(); i++) {
                List<String> lineObj = objList.get(i);
                XSSFRow row = sheet.createRow(i + 1);// 因为表头已经占用了第一行，所以后面生成的行需从第二行开始
                try {

                    for (int j = 0; j < lineObj.size(); j++) {
                        XSSFCell cell = row.createCell(j);
                        cell.setCellValue(lineObj.get(j).toString());
                    }
                } catch (Exception e) {
                    System.out.println("write line exception: " + lineObj.toString());
                }
            }
            FileOutputStream os = new FileOutputStream(filePath);
            wb.write(os);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void main(String[] args) throws Exception {
        run_analysis_netWx();
    }


}

